package org.opens.javaskill.algorithm;

import org.junit.Test;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Scanner;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

public class DataView {

    public static void main(String[] args) {
        InputDataEntity inputInfo = new InputDataEntity();
        inputInfo.getInputInfo();
        inputInfo.sort();
        inputInfo.print();
    }

    @Test
    public void sortList() {
        DataRowEntity v1 = new DataRowEntity();
        v1.setValue(2);
        DataRowEntity v2 = new DataRowEntity();
        v2.setValue(1);

        List<DataRowEntity> list = new ArrayList<>();
        list.add(v1);
        list.add(v2);

        list.sort(Comparator.comparing(DataRowEntity::getValue));
        System.out.println(list);
        list.sort(Comparator.comparing(DataRowEntity::getValue).reversed());
        System.out.println(list);

    }

}

class InputDataEntity {

    final static String UPPER_LEFT = "\u250c";
    final static String UPPER_RIGHT = "\u2510";
    final static String LOWER_LEFT = "\u2514";
    final static String LOWER_RIGHT = "\u2518";

    final static String TRANSVERSE = "\u2500"; // 横
    final static String VERTICAL = "\u2502"; // 竖

    final static String VERTICAL_RIGHT = "\u251c";
    final static String VERTICAL_LEFT = "\u2524";
    final static String TRANSVERSE_DOWN = "\u252c";
    final static String TRANSVERSE_UP = "\u2534";
    final static String CROSS = "\u253c";

    final static String COLUMN = "\u2588"; // 柱
    final static String SPACE = "\u0020";

    /**
     * 输入数据的行数
     */
    private Integer dataCount;

    /**
     * 输入的排序信息
     */
    private String orderInfo;

    /**
     * 输入的数据信息
     */
    private List<String> data;

    /**
     * 处理后的数据信息
     */
    private List<DataRowEntity> entityData;

    public Integer getDataCount() {
        return dataCount;
    }

    public void setDataCount(Integer dataCount) {
        this.dataCount = dataCount;
    }

    public String getOrderInfo() {
        return orderInfo;
    }

    public void setOrderInfo(String orderInfo) {
        this.orderInfo = orderInfo;
    }

    public List<String> getData() {
        return data;
    }

    public void setData(List<String> data) {
        this.data = data;
    }

    public List<DataRowEntity> getEntityData() {
        return entityData;
    }

    public void setEntityData(List<DataRowEntity> entityData) {
        this.entityData = entityData;
    }

    @Override
    public String toString() {
        return "InputDataEntity{" +
                "dataCount=" + dataCount +
                ", orderInfo='" + orderInfo + '\'' +
                ", data=" + data +
                ", entityData=" + entityData +
                '}';
    }

    /**
     * 功能: 从键盘获取输入信息
     */
    public void getInputInfo() {
        Scanner scanner = new Scanner(System.in);

        System.out.println("请输入:");
        Integer dataCount = 0;
        boolean dataCountValidInputSign = false;
        while (!dataCountValidInputSign) {
            String dataCountStr = scanner.nextLine();
            Pattern dataCountPattern = Pattern.compile("^\\d+$");
            Matcher matcher = dataCountPattern.matcher(dataCountStr);
            if (!matcher.matches()) {
                System.out.print("输入的字符非数字, 请重新输入:");
                continue;
            }
            dataCount = Integer.parseInt(dataCountStr);
            dataCountValidInputSign = true;
        }

        Pattern orderInfoPattern = Pattern.compile("^(Name|Value) (ASC|DESC)$");
        boolean orderInfoValidInputSign = false;
        String orderInfo = "";
        while (!orderInfoValidInputSign) {
            orderInfo = scanner.nextLine();
            Matcher matcher = orderInfoPattern.matcher(orderInfo);
            if (!matcher.matches()) {
                System.out.println("排序格式为: ^(Name|Value) (ASC|DESC)$");
                continue;
            }
            orderInfoValidInputSign = true;
        }


        List<String> data = new ArrayList<>();
        int inputCount = 0;
        while (inputCount < dataCount) {
            String dataTmp = scanner.nextLine();

            Pattern dataPattern = Pattern.compile(".+ .+");
            Matcher matcher = dataPattern.matcher(dataTmp);
            if (!matcher.matches()) {
                System.out.println("数据格式必须是: 空格隔开的两个信息");
                continue;
            }

            data.add(dataTmp);
            inputCount++;
        }

        this.setDataCount(dataCount);
        this.setOrderInfo(orderInfo);
        this.setData(data);
    }

    /**
     * 功能: 排序并处理获取到的信息
     */
    public void sort() {
        List<String> data = this.getData();
        String orderInfo = this.getOrderInfo();
        final String[] splitOrderInfo = orderInfo.split(" ");
        final String orderKey = splitOrderInfo[0];
        final String order = splitOrderInfo[1];
        // 转换
        List<DataRowEntity> collectData = data.stream().map(x -> {
            String[] splitRes = x.split(" ");
            DataRowEntity rowEntity = new DataRowEntity();
            rowEntity.setName(splitRes[0]);
            rowEntity.setValue(Integer.parseInt(splitRes[1]));
            return rowEntity;
        }).collect(Collectors.toList());

        // 根据输入的排序规则进行排序
        if ("Name".equals(orderKey)) {
            if ("ASC".equals(order)) {
                collectData.sort(Comparator.comparing(DataRowEntity::getName));
            } else if ("DESC".equals(order)) {
                collectData.sort(Comparator.comparing(DataRowEntity::getName).reversed());
            }
        } else if ("Value".equals(orderKey)) {
            if ("ASC".equals(order)) {
                collectData.sort(Comparator.comparing(DataRowEntity::getValue));
            } else if ("DESC".equals(order)) {
                collectData.sort(Comparator.comparing(DataRowEntity::getValue).reversed());
            }
        }

        this.setEntityData(collectData);
    }

    /**
     * 功能: 格式化打印信息
     */
    public void print() {
        // 找出长度最长的name
        String maxLengthName = this.getEntityData().stream().map(DataRowEntity::getName).max(Comparator.comparing(String::length)).get();
        // 找出value最大值
        Float maxValue = this.getEntityData().stream().map(DataRowEntity::getValue).max(Comparator.comparing(Integer::valueOf)).map(Float::valueOf).get();
        // 最大长度name的长度
        Integer maxNameLength = maxLengthName.length();
        // 设置value的100%对应的值
        Integer valueLength = 20;
        // 要打印的所有数据行
        List<String> printRow = new ArrayList<>();

        for (int i = 0; i < this.getEntityData().size(); i++) {
            DataRowEntity rowEntity = this.getEntityData().get(i);
            String row = "";
            // 第一行
            if (i == 0) {
                row += UPPER_LEFT;
                row += this.fill("", maxNameLength, TRANSVERSE, "left");
                row += TRANSVERSE_DOWN;
                row += this.fill("", valueLength, TRANSVERSE, "left");
                row += UPPER_RIGHT;
                printRow.add(row);

                row = "";
                row += VERTICAL;
                row += this.fill(rowEntity.getName(), maxNameLength, SPACE, "right");
                row += VERTICAL;
                row += this.fill(replaceNum2Char(Math.round(Math.floor(rowEntity.getValue() / maxValue * 20)), COLUMN), valueLength, SPACE, "left");
                row += VERTICAL;
                printRow.add(row);
            } else if (i == this.getEntityData().size() - 1) {  // 最后一行
                row += VERTICAL_RIGHT;
                row += this.fill("", maxNameLength, TRANSVERSE, "left");
                row += CROSS;
                row += this.fill("", valueLength, TRANSVERSE, "left");
                row += VERTICAL_LEFT;
                printRow.add(row);

                row = "";
                row += VERTICAL;
                row += this.fill(rowEntity.getName(), maxNameLength, SPACE, "right");
                row += VERTICAL;
                row += this.fill(replaceNum2Char(Math.round(Math.floor(rowEntity.getValue() / maxValue * 20)), COLUMN), valueLength, SPACE, "left");
                row += VERTICAL;
                printRow.add(row);

                row = "";
                row += LOWER_LEFT;
                row += this.fill("", maxNameLength, TRANSVERSE, "left");
                row += TRANSVERSE_UP;
                row += this.fill("", valueLength, TRANSVERSE, "left");
                row += LOWER_RIGHT;
                printRow.add(row);
            } else {    // 中间行
                row += VERTICAL_RIGHT;
                row += this.fill("", maxNameLength, TRANSVERSE, "left");
                row += CROSS;
                row += this.fill("", valueLength, TRANSVERSE, "left");
                row += VERTICAL_LEFT;
                printRow.add(row);

                row = "";
                row += VERTICAL;
                row += this.fill(rowEntity.getName(), maxNameLength, SPACE, "right");
                row += VERTICAL;
                row += this.fill(replaceNum2Char(Math.round(Math.floor(rowEntity.getValue() / maxValue * 20)), COLUMN), valueLength, SPACE, "left");
                row += VERTICAL;
                printRow.add(row);
            }
        }

        for (int i = 0; i < printRow.size(); i++) {
            System.out.println(printRow.get(i));
        }
    }

    /**
     * 功能: 将数字转换为对应长度的字符
     * @param number    数字
     * @param symbol    字符串格式的字符
     */
    private String replaceNum2Char(Long number, String symbol) {
        String res = "";
        for (long i = 0; i < number; i++) {
            res += symbol;
        }
        return res;
    }

    /**
     * 功能: 与杨辉三角中的fill方法同理, 填充图形的
     * @param value         被填充的值
     * @param alignmentLen  填充后的长度
     * @param fillSymbol    填充字符
     * @param position      对齐方式
     */
    private String fill(String value, Integer alignmentLen, String fillSymbol, String position) {
        String prefix = "";
        for (int i = 0; i < alignmentLen - value.length(); i++) {
            prefix += fillSymbol;
        }

        if ("left".equals(position)) {
            return value + prefix;
        } else if ("right".equals(position)) {
            return prefix + value;
        }

        return value;
    }

}

/**
 * 功能: 用户输入数据转换时存储数据的实体
 */
class DataRowEntity {

    private String name;

    private Integer value;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getValue() {
        return value;
    }

    public void setValue(Integer value) {
        this.value = value;
    }

    @Override
    public String toString() {
        return "DataRowEntity{" +
                "name='" + name + '\'' +
                ", value=" + value +
                '}';
    }
}